-module(info).
-export([infomanager/1]).

infomanager(init) -> 
    open(user,"user.txt"),
    open(term,"terminal.txt"),
    open(store,"store.txt"),
    open(disp,"dispatch.txt"),

    ets:new(user, [set,named_table]),
    ets:new(term, [set,named_table]),
    ets:new(store, [set,named_table]),
    ets:new(disp, [set,named_table]),

    ets:from_dets(user, user),
%    io:format("user list is ~w ~n",[ets:tab2list(user)]),
    ets:from_dets(term, term),
    ets:from_dets(store, store),
    ets:from_dets(disp, disp),

    infomanager(service);
infomanager(service) ->
    receive 
	{_Pid,TableName,insert,Key,Value} ->
	    _Ret = insert(TableName,Key,Value),
	    %Pid ! Ret,
	    infomanager(service);
	{Pid,TableName,lookup,Key} ->
	    Ret = lookup(TableName,Key),
	    Pid ! Ret,
	    infomanager(service);
	{_Pid,TableName,delete,Key} ->
            _Ret = delete(TableName,Key),
            infomanager(service);
	_Other ->
	    io:format("info service recv unknown msg~n"),
	    infomanager(service)
    after 120000 ->
	    infomanager(sync),
	    infomanager(service)    
    end;
infomanager(stop) ->
    close(user),
    close(term),
    close(store),
    close(disp);
infomanager(sync) ->
    sync(user),
    sync(term),
    sync(store),
    sync(disp).
    
open(TableName,File) ->

    Bool = filelib:is_file(File),
    
    case dets:open_file(TableName, [{file, File}]) of
	{ok, TableName} ->
	    case Bool of
		true  ->
		    void;
		false -> 
		    ok = dets:insert(TableName, {free,1})
	    end,
	    true;
	{error,_Reason} ->
	    io:format("cannot open dets table~n"),
	    error
    end.

close(TableName) -> 
    dets:close(TableName),
    ets:delete(TableName).

lookup(TableName,Key) ->
    case ets:lookup(TableName, Key) of %this use ets,dets only save
	[] -> 
	    {lookup,error,exception};
	[{_,Bin}] -> 
	    {lookup,ok,Bin}
    end.

insert(TableName,Key,Value) ->
    dets:insert(TableName, {Key,Value}),
    ets:insert(TableName, {Key,Value}),
    {insert,ok}.

delete(TableName,Key) ->
    dets:delete(TableName, Key),
    ets:delete(TableName, Key),
    {delete,ok}.

sync(TableName) ->
    dets:sync(TableName).
